package it.lorenz.server.fk.business.mail;

import it.lorenz.server.fk.business.ex.ValidationException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.stereotype.Component;

@Component("mailValidator")
public class MailValidator implements IMailValidator {

    private Pattern pattern;

    public MailValidator() {
        this("^[a-zA-Z0-9._%+-]+@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,4}$");
    }

    public MailValidator(String pattern) {
        this.pattern = Pattern.compile(pattern);
    }

    @Override
    public void doFormalValidation(MailDTO dto) throws ValidationException {
        ValidationException vex = new ValidationException();

        Matcher matcher = null;

        if (dto.getFrom() != null) {
            matcher = pattern.matcher(dto.getFrom());
            if (!matcher.matches()) {
                addInvalidAddress(vex, "from", dto.getFrom());
            }
        }

        if (dto.getBounceEmail() != null) {
            matcher = pattern.matcher(dto.getBounceEmail());
            if (!matcher.matches()) {
                addInvalidAddress(vex, "bounceEmail", dto.getBounceEmail());
            }
        }

        if (dto.getTos() != null && dto.getTos().size() > 0) {
            for (String to : dto.getTos()) {
                matcher = pattern.matcher(to);
                if (!matcher.matches()) {
                    addInvalidAddress(vex, "tos", to);
                }
            }
        }

        if (dto.getCcs() != null && dto.getCcs().size() > 0) {
            for (String cc : dto.getCcs()) {
                matcher = pattern.matcher(cc);
                if (!matcher.matches()) {
                    addInvalidAddress(vex, "ccs", cc);
                }
            }
        }

        if (dto.getBccs() != null && dto.getBccs().size() > 0) {
            for (String bcc : dto.getBccs()) {
                matcher = pattern.matcher(bcc);
                if (!matcher.matches()) {
                    addInvalidAddress(vex, "bccs", bcc);
                }
            }
        }

        if (vex.haveMessages()) {
            throw vex;
        }
    }

    private void addInvalidAddress(ValidationException vex, String field,
       String value) {
        vex.addFieldMessage(field, String.format(
           "%s non e' un indirizzo email valido", value));
    }

    @Override
    public void doFunctionalValidation(MailDTO dto) throws ValidationException {
        ValidationException vex = new ValidationException();

        if (dto.getFrom() == null) {
            vex.addFieldMessage("from",
               "l'indirizzo from va sempre valorizzato");
        }

        if (dto.getTos() == null || dto.getTos().size() == 0) {
            vex.addFieldMessage("tos",
               "deve esistere almeno un indirizzo a cui inviare l'email");
        }

        if (vex.haveMessages()) {
            throw vex;
        }
    }
}
